package com.xqboss.apps.controller.user;

import com.xqboss.apps.constant.Config;
import com.xqboss.apps.convert.user.WithdrawConverter;
import com.xqboss.apps.domain.param.AesParams;
import com.xqboss.apps.domain.user.SysUserWalletWithdraw;
import com.xqboss.apps.domain.user.SysUserWalletWithdrawHandler;
import com.xqboss.apps.dto.user.ApplyWithdrawDto;
import com.xqboss.apps.dto.user.CalcWithdrawFeeDto;
import com.xqboss.apps.dto.user.GetWithdrawListDto;
import com.xqboss.apps.dto.user.UserGetWithdrawListDto;
import com.xqboss.apps.enums.user.UserWalletEnum;
import com.xqboss.apps.mapper.user.SysUserWalletWithdrawMapper;
import com.xqboss.apps.service.consumer.ConsumerRealNameService;
import com.xqboss.apps.service.user.SysUserWalletWithdrawHandlerService;
import com.xqboss.apps.service.user.SysUserWalletWithdrawService;
import com.xqboss.apps.util.mh.BeanCopierUtil;
import com.xqboss.apps.vo.user.*;
import com.xqboss.common.annotation.RepeatSubmit;
import com.xqboss.common.core.controller.BaseController;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.StringUtils;
import com.xqboss.common.utils.ValidatorUtil;
import com.xqboss.common.utils.aes.AesUtil;
import com.xqboss.system.service.ISysConfigService;
import com.xqboss.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 用户钱包提现相关控制器
 * </p>
 *
 * @author Trent
 * @date 2023/8/17
 */

@Api(tags = "钱包-用户钱包提现管理")
@RestController
@RequestMapping("/user/wallet/withdraw")
public class UserWalletWithdrawController extends BaseController {

    @Autowired
    private SysUserWalletWithdrawService userWalletWithdrawService;

    @Autowired
    private SysUserWalletWithdrawMapper userWalletWithdrawMapper;

    @Autowired
    private SysUserWalletWithdrawHandlerService userWalletWithdrawHandlerService;

    @Autowired
    private WithdrawConverter withdrawConverter;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ConsumerRealNameService realNameService;

    @Autowired
    private ISysConfigService sysConfigService;

    /**
     * 提现列表
     *
     * @return
     */

    @RepeatSubmit(interval = 1000, justUrl = true)
    @ApiOperation("申请提现")
    @PostMapping("apply")
    public R apply(@Validated @RequestBody AesParams param) {
        Boolean enable = sysConfigService.getValue(Config.Sys.Withdraw.提现功能开启状态);
        if(!enable){
            throw new ServiceException("提现功能暂未开放！");
        }
        ApplyWithdrawDto params = AesUtil.decryptToObject(param.getParamStr(), ApplyWithdrawDto.class);
        // 做下手动参数校验
        ValidatorUtil.valid(params);
        // 提现金额校验
        BigDecimal minPrice = sysConfigService.getValue(Config.Sys.Withdraw.单次提现最低金额);
        BigDecimal maxPrice = sysConfigService.getValue(Config.Sys.Withdraw.单次提现最高金额);
        if(Objects.nonNull(minPrice)){
            if(params.getAmount().compareTo(minPrice) < 0){
                if(Objects.isNull(maxPrice)){
                    throw new ServiceException(StringUtils.format("单次最低提现：{}!", minPrice));
                }else{
                    throw new ServiceException(StringUtils.format("提现金额范围：{} - {}!", minPrice, maxPrice));
                }
            }
        }

        if(Objects.nonNull(maxPrice)){
            if(params.getAmount().compareTo(maxPrice) > 0){
                if(Objects.isNull(minPrice)){
                    throw new ServiceException(StringUtils.format("单次最多提现{}!", maxPrice));
                }else{
                    throw new ServiceException(StringUtils.format("提现金额范围：{} - {}!", minPrice, maxPrice));
                }
            }
        }


        //实名用户才能充值
        realNameService.requireRealName(getUserId());
        //检测支付密码
        userService.checkPayPwd(getUserId(), params.getPayPwd());
        //校验用户钱包记录与当前余额是否一致
        CheckUserWalletVo checkUserWalletVo = userWalletWithdrawMapper.checkWalletAmount(getUserId(), UserWalletEnum.CASH.getValue());
        if (Objects.isNull(checkUserWalletVo) || checkUserWalletVo.getWalletAmount().compareTo(checkUserWalletVo.getRecordAmount()) != 0) {
            throw new ServiceException("1余额不足！");
        }
        SysUserWalletWithdraw withdrawInfo = BeanCopierUtil.copy(params, SysUserWalletWithdraw.class);
        withdrawInfo.setUserId(getUserId());
        userWalletWithdrawService.applyWithdraw(withdrawInfo);
        return R.ok();
    }

    /**
     * 提现列表
     *
     * @return
     */
    @ApiOperation("提现列表")
    @GetMapping("list")
    public R<List<WithdrawListVo>> withdrawList(@Validated UserGetWithdrawListDto params) {
        startPage();
        GetWithdrawListDto withdrawListDto = BeanCopierUtil.copy(params, GetWithdrawListDto.class);
        withdrawListDto.setUserId(getUserId());
        List<WithdrawListVo> list = userWalletWithdrawService.getVoList(withdrawListDto);
        return R.ok(list);
    }

    /**
     * 提现详情
     *
     * @return
     */
    @ApiOperation("提现详情")
    @GetMapping("detail/{withdrawId}")
    public R<AppWithdrawDetailVo> withdrawList(@Validated @PathVariable("withdrawId")
                                                @ApiParam(value = "提现ID", required = true)
                                                @NotNull(message = "提现ID不能为空")
                                                Long withdrawId) {
        WithdrawListVo detail = userWalletWithdrawService.getDetail(withdrawId);
        if(!Objects.equals(detail.getUserId(), getUserId())){
            throw new ServiceException("提现不存在！");
        }
        List<SysUserWalletWithdrawHandler> handlerList = userWalletWithdrawHandlerService.getWithdrawHandlerList(detail.getId());
        AppWithdrawDetailVo result = withdrawConverter.toAppWithdrawDetailVo(detail, handlerList);
        return R.ok(result);
    }

    /**
     * 提现信息
     *
     * @return
     */
    @ApiOperation("提现统计信息")
    @GetMapping("withdraw/static")
    public R<AppWithdrawStaticInfoVo> withdrawStatic() {
        Long userId = getUserId();
        AppWithdrawStaticInfoVo vo = userWalletWithdrawService.getWithdrawStatic(userId);
        return R.ok(vo);
    }


    /**
     * 提现信息
     *
     * @return
     */
    @ApiOperation("计算提现手续费")
    @PostMapping("calc-fee")
    public R<AppWithdrawFeeVo> calcWithdrawFee(@Validated @RequestBody CalcWithdrawFeeDto dto) {
        Long userId = getUserId();
        AppWithdrawFeeVo vo = userWalletWithdrawService.calcWithdrawFee(userId, dto.getAmount());
        return R.ok(vo);
    }
}
